#include<stdio.h>
#include<string.h>
#include<signal.h>
#include<setjmp.h>
#include<unistd.h>
#include<stdlib.h>
#include<time.h>
#include<errno.h>

void sig_usr1(int signo);
void sig_alrm(int signo);
void pr_mask(const char *str);

static sigjmp_buf              jmpbuf;
static volatile sig_atomic_t   canjump;

int main(int argc,char **argv)
{
	if(signal(SIGUSR1,sig_usr1) == SIG_ERR)
		printf("signal(SIGUSR1) error\n");

	if(signal(SIGALRM,sig_alrm) == SIG_ERR)
		printf("signal(SIGALRM) error\n");

	pr_mask("\nstarting main: ");

	if(sigsetjmp(jmpbuf,1))
	{
		pr_mask("ending main: ");

		exit(0);
	}

	canjump = 1;

	for( ; ; )
	{
		pause();
	}
}

void sig_usr1(int signo)
{
	time_t      starttime;

	if(canjump == 0)
		return;

	pr_mask("\nstarting sig_usr1: ");

	alarm(3);
	starttime = time(NULL);
	for( ; ; )
	{
		if(time(NULL) > starttime + 5)
			break;

	}

	pr_mask("finishing sig_usr1: ");

	canjump = 0;
	siglongjmp(jmpbuf,1);
}

void sig_alrm(int signo)
{
	pr_mask("in sig_alrm:");
}

void pr_mask(const char *str)
{
	sigset_t         sigset;
	int              errno_save;

	errno_save = errno;
	if(sigprocmask(0,NULL,&sigset) < 0)
		printf("sigprocmask error\n");

	else
	{
		printf("%s",str);
		if(sigismember(&sigset,SIGINT))
			printf("SIGINT");

		if(sigismember(&sigset,SIGQUIT))
			printf("SIGQUIT");

		if(sigismember(&sigset,SIGUSR1))
			printf("SIGUSR1");

	    if(sigismember(&sigset,SIGALRM))
			printf("SIGALRM");

	    printf("\n");
	}
	errno = errno_save;
}
